package montaltoGrids
import scala.collection.mutable.Stack
import scala.collection.mutable.Queue
import montaltoFood._
import montaltoNeds._
import montaltoUtils._
import montaltoView._
import montaltoController._
import collection.jcl.ArrayList

/**
 * Created by IntelliJ IDEA.
 * User: Andrew Montalto
 * Date: Apr 25, 2010
 * Time: 12:00:09 PM
 * To change this template use File | Settings | File Templates.
 */
class Coordinate(pX:Int,pY:Int){
  var x:Int= pX
  var y:Int= pY
  def getCoodinate():String={
    return "("+x.toString() +"," + y.toString() + ")"
  }

}
trait iGridPiece

class GridPiece(coord:Coordinate) extends iGridPiece{
  val coodinate = coord
  var foodStack:Stack[Food] = new Stack[Food]
  var neds= new ArrayList[Ned]
 
  //adds foods to the grid
  def growFood()={
   val maxFoodToGrow = 3
   var r = RandomSingleton.INSTANCE.nextPosInt(maxFoodToGrow)
   for(i <- 1 to r) {
      foodStack.push(RandomFood.get)
    }
  }


  def getTopFood():Food={
    if(!foodStack.isEmpty){
      return foodStack.pop
    }else{
      return new NoFood
    }
  }

  def settleNed(ned:Ned)={
    neds.add(ned)
  }
  def removeNed(index:Int):Ned={
     return neds.remove(index)
  }

}
//created an abstract class to we can create new
// methods for populating the grid



class Grid(size:Int) {
  var turn = 0
  def _size = size
  val observers:Queue[NedObserver] = new Queue
  val gridArray= new Array[Array[GridPiece]](size,size)

  for{
    i<-gridArray.indices
    j<-gridArray(i).indices
  }gridArray(i)(j)=  new GridPiece(new Coordinate(i,j))

  def populateWithNedsRandomly(total:Int)={
     var populate = new PopulateGridRandom(this,total)
     populate.populate
  }


  def RegisterObservers(observer:NedObserver)={
    observers.enqueue(observer)
  }
  def Notify()={
    observers.foreach{o:NedObserver => o.update(this)}
  }
  def PrintResults={
     observers.foreach{o:NedObserver => o.printResults}
  }
  
  def countLivingNeds():Int={
    val myIter = GridIteratorCreator.create(this)
    var cnt = 0;
    while (myIter.hasNext){
      myIter.current().neds.foreach{n:Ned=>
      if(n.isAlive) cnt=cnt + 1
      }
      myIter.next
    }
    return cnt;
  }
}

//iterator design pattern

object GridIteratorCreator {
  def create(grid:Grid):MyIterator[GridPiece]={
    return new GridIterator(grid)
  }
}

class GridIterator(grid:Grid) extends MyIterator[GridPiece]{
  private var _grid:Grid=grid
  val i:Int = _grid.gridArray.indices.length
  val j:Int = _grid.gridArray.indices.length
  var y:Int = 1
  var x:Int = 1
  def getX():Int={
    return y-1
  }
  def getY():Int={
    return x-1
  }

  def current():GridPiece =
  {
    return _grid.gridArray(getX)(getY)
  }

  def hasNext():Boolean = {
    if(x < j+1){
      return true
    }
    return false
  }

  def next():Unit  ={
    if (hasNext()){
        if(y % i == 0){
            y = (y % i)+ 1;
            x = x + 1
          }
        else{
          y = y + 1
        }
    }
 }

  def first():Unit ={
    y = 1
    x = 1
  }
   
}
